/*
 * @Author: liusheng
 * @Date: 2022-04-19 16:52:53
 * @LastEditors: liusheng
 * @LastEditTime: 2022-04-19 17:10:49
 * @Description: 剑指 Offer II 034. 外星语言是否排序
 * email:liusheng613@126.com
 * Copyright (c) 2022 by liusheng/liusheng, All Rights Reserved. 
 
 剑指 Offer II 034. 外星语言是否排序
某种外星语也使用英文小写字母，但可能顺序 order 不同。字母表的顺序（order）是一些小写字母的排列。

给定一组用外星语书写的单词 words，以及其字母表的顺序 order，只有当给定的单词在这种外星语中按字典序排列时，返回 true；否则，返回 false。

 

示例 1：

输入：words = ["hello","leetcode"], order = "hlabcdefgijkmnopqrstuvwxyz"
输出：true
解释：在该语言的字母表中，'h' 位于 'l' 之前，所以单词序列是按字典序排列的。
示例 2：

输入：words = ["word","world","row"], order = "worldabcefghijkmnpqstuvxyz"
输出：false
解释：在该语言的字母表中，'d' 位于 'l' 之后，那么 words[0] > words[1]，因此单词序列不是按字典序排列的。
示例 3：

输入：words = ["apple","app"], order = "abcdefghijklmnopqrstuvwxyz"
输出：false
解释：当前三个字符 "app" 匹配时，第二个字符串相对短一些，然后根据词典编纂规则 "apple" > "app"，因为 'l' > '∅'，其中 '∅' 是空白字符，定义为比任何其他字符都小（更多信息）。
 

提示：

1 <= words.length <= 100
1 <= words[i].length <= 20
order.length == 26
在 words[i] 和 order 中的所有字符都是英文小写字母。
 

注意：本题与主站 953 题相同： https://leetcode-cn.com/problems/verifying-an-alien-dictionary/
 */

#include "header.h"

class Solution {
public:
    bool isAlienSorted(vector<string>& words, string order) {
        unordered_map<char,char> reorder;

        //hashmap for every character
        //build the new order
        for (int i = 0; i < 26; ++i)
        {
            reorder[order[i]] = i;
        }

        auto alienStrLECompare = [&](const string & str1,const string & str2) 
        {
            int len1 = str1.size();
            int len2 = str2.size();
            int index = 0;
            while (index < len1 && index < len2)
            {
                if (reorder[str1[index]] < reorder[str2[index]])
                {
                    return true;
                }
                else if(reorder[str1[index]] > reorder[str2[index]])
                {
                    return false;
                }
                ++index;
            }
            
            return len1 > len2 ? false:true;
        };

        for (int i = 0; i < words.size() - 1; ++i)
        {
            //words[i] > words[i + 1],return false
            if (!alienStrLECompare(words[i],words[i+1]))
            {
                return false;
            }
        }

        return true;
    }
};

//similar to solution1,but use array as the reorder num key
class Solution2 {
public:
    bool isAlienSorted(vector<string>& words, string order) {
        array<char,26> reorder;
        //build the new order
        for (int i = 0; i < 26; ++i)
        {
            reorder[order[i] - 'a'] = i;
        }
        
        auto alienLEStrCmp = [&] (string & str1, string & str2) -> bool
        {
            int len1 = str1.size();
            int len2 = str2.size();
            int index = 0;
            while (index < len1 && index < len2)
            {
                //only character is equal,then continue compare
                //else the result is come,so return immediately 
                if (reorder[str1[index] - 'a'] < reorder[str2[index] - 'a'])
                {
                    return true;
                }
                else if (reorder[str1[index] - 'a'] > reorder[str2[index] - 'a'])
                {
                    return false;
                }
                ++index;
            }
            
            return len1 <= len2 ? true:false;
        };
        
        int wordNum = words.size();
        for (int i = 0; i < wordNum - 1; ++i)
        {
            if (!alienLEStrCmp(words[i],words[i+1]))
            {
                return false;
            }
        }
        return true;
    }
};